﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace VkSample113;

public class TreeTrunkData
{
    public float[] Data { get; set; }
    public int DataBytes { get; set; }
    public int VCount { get; set; }

    public void GenVertexData(float bottom_radius, float joint_Height, int jointNum, int availableNum)
    {
        float longitude_span = 12;
        List<float> alVertix = new List<float>();
        List<float> alTexCoor = new List<float>();
        for (int num = 0; num < availableNum; num++)
        {
            float temp_bottom_radius = bottom_radius * (jointNum - num) / (float)jointNum;
            //此节树干顶端半径
            float temp_top_radius = bottom_radius * (jointNum - (num + 1)) / (float)jointNum;
            //此节树干底端的y坐标
            float temp_bottom_height = num * joint_Height;
            //此节树干顶端的y坐标
            float temp_top_height = (num + 1) * joint_Height;
            for (float hAngle = 0; hAngle < 360; hAngle = hAngle + longitude_span)
            {
                //当前四边形左上点X、Y、Z坐标
                float x0 = (float)(temp_top_radius * MathF.Cos(toRadians(hAngle)));
                float y0 = temp_top_height;
                float z0 = (float)(temp_top_radius * MathF.Sin(toRadians(hAngle)));
                //当前四边形左下点X、Y、Z坐标
                float x1 = (float)(temp_bottom_radius * MathF.Cos(toRadians(hAngle)));
                float y1 = temp_bottom_height;
                float z1 = (float)(temp_bottom_radius * MathF.Sin(toRadians(hAngle)));
                //当前四边形右上点X、Y、Z坐标
                float x2 = (float)(temp_top_radius * MathF.Cos(toRadians(hAngle + longitude_span)));
                float y2 = temp_top_height;
                float z2 = (float)(temp_top_radius * MathF.Sin(toRadians(hAngle + longitude_span)));
                //当前四边形右下点X、Y、Z坐标
                float x3 = (float)(temp_bottom_radius * MathF.Cos(toRadians(hAngle + longitude_span)));
                float y3 = temp_bottom_height;
                float z3 = (float)(temp_bottom_radius * MathF.Sin(toRadians(hAngle + longitude_span)));
                //将顶点坐标按照卷绕成两个三角形的顺序依次放入顶点坐标列表
                alVertix.Add(x0); alVertix.Add(y0); alVertix.Add(z0);
                alVertix.Add(x1); alVertix.Add(y1); alVertix.Add(z1);
                alVertix.Add(x2); alVertix.Add(y2); alVertix.Add(z2);

                alVertix.Add(x2); alVertix.Add(y2); alVertix.Add(z2);
                alVertix.Add(x1); alVertix.Add(y1); alVertix.Add(z1);
                alVertix.Add(x3); alVertix.Add(y3); alVertix.Add(z3);
            }
            var texcoor = GenerateTexCoor((int)(360 / longitude_span), 1);
            for (int i = 0; i < 360; i++)
            {
                alTexCoor.Add(texcoor[i]);
            }
        }
        VCount = alVertix.Count / 3;//得到顶点数量
        DataBytes = VCount * 5 * sizeof(float);//计算数据所占字节数
        Data = new float[VCount * 5];//创建存放数据的数组
        int index = 0;//辅助索引
        for (int i = 0; i < VCount; i++)
        {//将顶点数据和纹理坐标数据存储到数组中
            Data[index++] = alVertix[i * 3 + 0];
            Data[index++] = alVertix[i * 3 + 1];
            Data[index++] = alVertix[i * 3 + 2];
            Data[index++] = alTexCoor[i * 2 + 0];
            Data[index++] = alTexCoor[i * 2 + 1];
        }
    }

    private float toRadians(float degree)
    {//角度转换成弧度的方法
        return (float)degree * MathF.PI / 180;
    }
    private List<float> GenerateTexCoor(int bw, int bh)
    {
        List<float> result = new List<float>();
        float sizew = 1.0f / bw;//列数
        float sizeh = 1.0f / bh;//行数
        for (int i = 0; i < bh; i++)
        {
            for (int j = 0; j < bw; j++)
            {
                //每行列一个矩形，由两个三角形构成，共六个点，12个纹理坐标
                float s = j * sizew;
                float t = i * sizeh;

                result.Add(s);
                result.Add(t);

                result.Add(s);
                result.Add(t + sizeh);

                result.Add(s + sizew);
                result.Add(t);

                result.Add(s + sizew);
                result.Add(t);

                result.Add(s);
                result.Add(t + sizeh);

                result.Add(s + sizew);
                result.Add(t + sizeh);
            }
        }
        return result;
    }
}
